package com.xjgzinfo.usdp.web.rest;

import com.xjgzinfo.usdp.constant.AuthConstant;
import com.xjgzinfo.usdp.core.domain.ResponseResult;
import com.xjgzinfo.usdp.security.SecurityUtils;
import com.xjgzinfo.usdp.service.AppFileService;
import com.xjgzinfo.usdp.service.dto.AppFileDTO;
import com.zaxxer.hikari.HikariDataSource;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static com.xjgzinfo.usdp.constant.SystemConstant.FILE_DIRS;

/**
 * REST controller for managing {@link com.xjgzinfo.usdp.domain.AppFile}.
 */
@RestController
@RequestMapping("/blade-visual")
public class AppFileResource {

    private static final String ENTITY_NAME = "AppFile";
    private final Logger log = LoggerFactory.getLogger(AppFileResource.class);
    private final String DEFAULT_FILE_BUCKET = "app-files";
    private final AppFileService appFileService;
    private final JwtDecoder jwtDecoder;
    private final MinioClient minioClient;
    @Value("${spring.application.name:usdp-app-unkown}")
    private String applicationName;
    @Value("${minio.host:http://localhost:9000}")
    private String miniHost;
    @Value("${minio.url:http://minio:9000}")
    private String miniUrl;

    public AppFileResource(AppFileService appFileService, JwtDecoder jwtDecoder, MinioClient minioClient) {
        this.appFileService = appFileService;
        this.jwtDecoder = jwtDecoder;
        this.minioClient = minioClient;
    }

    /**
     * {@code POST  /app-files/upload} : 上传文件.
     *
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the map, or with status {@code 404 (Not Found)}.
     */
    @PostMapping(value = "/app-files/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseResult<Map<String, String>> upload(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(name = "type", required = false, defaultValue = "0") int type) {
        Map<String, String> result = new HashMap<>();
        AppFileDTO appFileDTO = new AppFileDTO();
        try (InputStream ins = file.getInputStream()) {
            // 获取文件输入流
            String fileName = file.getOriginalFilename() != null ? file.getOriginalFilename() : Instant.now().getEpochSecond() + (type == 0 ? ".jpg" : ".dat");

            PutObjectOptions putObjectOptions = new PutObjectOptions(file.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);
            // 文件的ContentType
            putObjectOptions.setContentType(file.getContentType());
            minioClient.putObject(DEFAULT_FILE_BUCKET, FILE_DIRS[type] + "/" + fileName, ins, putObjectOptions);
            String link = minioClient.getObjectUrl(DEFAULT_FILE_BUCKET, FILE_DIRS[type] + "/" + fileName);
            if (link != null) {
                result.put("link", link.replace(miniHost, miniUrl));
                appFileDTO.setFileId(Instant.now().getEpochSecond());
                appFileDTO.setOriginalFileName(file.getOriginalFilename());
                appFileDTO.setFileName(file.getName());
                appFileDTO.setFilePath(FILE_DIRS[type] + "/" + fileName);
                appFileDTO.setFileUri(result.get("link"));
            }
            Optional<String> jwtOptions = SecurityUtils.getCurrentUserJWT();
            if (jwtOptions.isPresent()) {
                Jwt jwt = jwtDecoder.decode(jwtOptions.get());
                long userId = Long.valueOf(jwt.getClaims().get(AuthConstant.USERID_CLAIM).toString());
                appFileDTO.setUserId(userId);
                appFileService.save(appFileDTO);
            }
            result.put("name", fileName);
            return new ResponseResult(200, result, "", true);
        } catch (Exception e) {
            return new ResponseResult(400, null, e.getMessage(), false);
        }
    }
}
